<template>
  <Form
    :model="formState"
    ref="formRef"
    class="md:flex-row w-full flex-wrap"
    layout="inline"
    v-model="props.initData"
    v-bind="formItemLayout"
  >
    <div class="md:flex w-full md:justify-between items-center">
      <div class="md:flex md:justify-start">
        <Col :span="9">
          <FormItem name="timeRange" label="时间范围">
            <RangePicker
              v-model:value="timeRange"
              :format="format"
              :ranges="timeRangeOptions"
              show-time
              style="width: 350px"
              @change="onTimeRangeChange"
              :disabledDate="disabledDate"
              @calendarChange="onCalendarChange"
              @openChange="onOpenChange"
            ></RangePicker>
          </FormItem>
        </Col>
        <Col :span="5">
          <FormItem name="tenant" label="租户">
            <Select
              v-model:value="tenants"
              placeholder="请选择租户（可多选）"
              mode="multiple"
              :max-tag-count="maxTagCount"
              :max-tag-text-length="maxTagTextLength"
              :options="tenantOptions"
              :allowClear="true"
              :disabled="tenantDisabled"
              @change="onTenantChange"
              style="width: 200px"
            >
            </Select>
          </FormItem>
        </Col>
        <Col :span="5">
          <FormItem name="app" label="应用">
            <Select
              v-model:value="apps"
              placeholder="请选择应用（可多选）"
              mode="multiple"
              :max-tag-count="maxTagCount"
              :max-tag-text-length="maxTagTextLength"
              :options="appOptions"
              :allowClear="true"
              :disabled="appDisabled"
              @change="onAppChange"
              style="width: 200px"
            >
            </Select>
          </FormItem>
        </Col>
        <Col :span="7">
          <FormItem name="service" label="服务">
            <Select
              v-model:value="services"
              placeholder="请选择实例（可多选）"
              mode="multiple"
              :max-tag-count="maxTagCount"
              :max-tag-text-length="24"
              :options="serviceOptions"
              :allowClear="true"
              :disabled="serviceDisabled"
              style="width: 260px"
            >
            </Select>
          </FormItem>
        </Col>
      </div>
      <FormItem>
        <div class="md:flex md:justify-end">
          <Button type="primary" shape="circle" @click="onSubmit">
            <template #icon><SearchOutlined /></template>
          </Button>
          <Button style="margin-left: 5px" shape="circle" @click="resetForm">
            <template #icon> <RedoOutlined /> </template>
          </Button>
        </div>
      </FormItem>
    </div>
  </Form>
</template>

<script lang="ts">
/* eslint-disable */
import { defineComponent, reactive, ref, onMounted } from 'vue';
import moment from 'moment';
import { Button, Row, Col, Form, FormItem, Select, SelectOption, RangePicker } from 'ant-design-vue';
import { SearchOutlined, RedoOutlined } from '@ant-design/icons-vue';
import { DurationDto } from '/@/api/maintenance-center/skywalking/common/model/commonModel';
import {
  QueryServicesByApp,
  QueryTopoAppsByTenant,
} from '/@/api/maintenance-center/skywalking/topology/model/topologyModel';
import {
  getTopoAppsByTenant,
  getTopoServicesByApp,
  getTopoTenants,
} from '/@/api/maintenance-center/skywalking/topology/topology';
import dayjs, { Dayjs } from 'dayjs';
export default defineComponent({
  components: {
    Button,
    Row,
    Col,
    Form,
    FormItem,
    Select,
    SelectOption,
    SearchOutlined,
    RangePicker,
    RedoOutlined,
  },
  props: {
    initData: Object,
  },
  setup(props, { emit }) {
    const formRef = ref();
    const formState = reactive<Record<string, any>>({});

    const formItemLayout = {
      labelCol: { span: 5 },
      wrapperCol: { span: 24 },
    };

    // Select 组件属性设置
    const tenants = ref([]);
    const tenantOptions = ref<any>([]);
    const tenantDisabled = ref(true);

    const apps = ref([]);
    const appOptions = ref<any[]>([]);
    const appDisabled = ref(true);

    const services = ref();
    const serviceOptions = ref<any[]>([]);
    const serviceDisabled = ref(true);

    const maxTagCount = ref(1);
    const maxTagTextLength = ref(5);

    const timeRange = ref<RangeValue>();
    type RangeValue = [Dayjs, Dayjs];
    const timeRangeOptions = {
      最近15分钟: [dayjs().subtract(15, 'minute'), dayjs()] as RangeValue,
      最近30分钟: [dayjs().subtract(30, 'minute'), dayjs()] as RangeValue,
      最近1小时: [dayjs().subtract(1, 'hour'), dayjs()] as RangeValue,
      最近1天: [dayjs().subtract(1, 'day'), dayjs()] as RangeValue,
      最近1周: [dayjs().subtract(1, 'week'), dayjs()] as RangeValue,
      最近1月: [dayjs().subtract(1, 'month'), dayjs()] as RangeValue,
      最近2月: [dayjs().subtract(2, 'month'), dayjs()] as RangeValue,
    };
    const format = ref<string>('YYYY-MM-DD HH:mm:ss');
    const showTime = {
      format: 'HH:mm:ss',
      defaulValue: [moment().format('HH:mm:ss'), moment().format('HH:mm:ss')],
    };
    const stepFormatMap = {
      SECOND: 'YYYY-MM-DD HHmmss',
      MINUTE: 'YYYY-MM-DD HHmm',
      HOUR: 'YYYY-MM-DD HH',
      DAY: 'YYYY-MM-DD',
      MONTH: 'YYYY-MM',
    };
    let disabledCurrent: any = null;
    let isHandOperated = false;
    function onOpenChange(status: boolean) {
      if (status) {
        disabledCurrent = timeRange.value;
      } else {
        // 清空禁用时间段
        disabledCurrent = null;
      }
    }

    function onCalendarChange(dates: [Dayjs, Dayjs]) {
      // 选择timeRangeOptions
      if (dates && dates[0] && dates[1]) {
        return;
      }
      // 手动选择
      if (dates !== null) {
        isHandOperated = true;
        disabledCurrent = dates;
        return;
      }
    }

    function disabledDate(current: Dayjs) {
      if (!disabledCurrent) {
        return false;
      }
      // 选择完重新选择时间的场景
      if (disabledCurrent[0] && disabledCurrent[1]) {
        return (
          current && (current > disabledCurrent[0].add(2, 'month') || current < disabledCurrent[1].subtract(2, 'month'))
        );
      }
      if (disabledCurrent[0]) {
        return current && current > disabledCurrent[0].add(2, 'month');
      }
      if (disabledCurrent[1]) {
        return current && current < disabledCurrent[1].subtract(2, 'month');
      }
    }

    let durationParam: DurationDto = {
      start: '',
      end: '',
      step: '',
    };

    const onTimeRangeChange = (data) => {
      if (data != null && data != undefined && data.length != 0) {
        let startTime = data[0];
        let endTime = data[1];
        let step = '';

        durationParam = processDuration(startTime, endTime, step, durationParam);

        tenantDisabled.value = false;

        getTopoTenants().then((res) => {
          tenantOptions.value = res.map((item) => ({
            label: item.tenantName,
            value: item.tenantCode,
          }));
        });
      } else {
        tenantDisabled.value = true;
        appDisabled.value = true;
        serviceDisabled.value = true;
        tenants.value = [];
        apps.value = [];
        services.value = undefined;
      }
    };

    const onTenantChange = (data, option) => {
      if (data != null && data != '' && data != undefined) {
        let appParams: QueryTopoAppsByTenant = {
          tenantCodes: data,
        };

        appDisabled.value = false;

        getTopoAppsByTenant(appParams).then((res) => {
          appOptions.value = res.map((item) => ({ label: item.appName, value: item.appId }));
        });
      } else {
        appDisabled.value = true;
        apps.value = [];
      }
    };

    const onAppChange = (data, option) => {
      if (data != null && data != '' && data != undefined) {
        let serviceParams: QueryServicesByApp = {
          appIds: data,
          tenantCodes: tenants.value,
        };

        serviceDisabled.value = false;

        getTopoServicesByApp(serviceParams).then((res) => {
          serviceOptions.value = res.map((item) => ({ label: item, value: item }));
        });
      } else {
        serviceDisabled.value = true;
        services.value = [];
      }
    };

    // 提交表单参数
    const onSubmit = async () => {
      formRef.value.validate().then(() => {
        let submitParams = {
          duration: durationParam,
          tenants: tenants.value,
          apps: apps.value,
          services: services.value,
        };
        emit('success', submitParams);
      });
    };

    // 清空表单参数
    const resetForm = () => {
      timeRange.value = [];
      tenantOptions.value = [];
      appOptions.value = [];
      serviceOptions.value = [];
      tenants.value = [];
      apps.value = [];
      services.value = [];
      tenantDisabled.value = true;
      appDisabled.value = true;
      serviceDisabled.value = true;
    };

    function processDuration(
      startTime: moment.Moment,
      endTime: moment.Moment,
      step: string,
      durationParam: DurationDto
    ) {
      if (startTime.second() !== endTime.second() && !isHandOperated) {
        step = 'SECOND';
        durationParam.start = startTime.format(stepFormatMap.SECOND);
        durationParam.end = endTime.format(stepFormatMap.SECOND);
      } else if (startTime.minute() !== endTime.minute() && !isHandOperated) {
        step = 'MINUTE';
        durationParam.start = startTime.format(stepFormatMap.MINUTE);
        durationParam.end = endTime.format(stepFormatMap.MINUTE);
      } else if (startTime.hour() !== endTime.hour()) {
        step = 'HOUR';
        durationParam.start = startTime.format(stepFormatMap.HOUR);
        durationParam.end = endTime.format(stepFormatMap.HOUR);
      } else if (startTime.day() !== endTime.day()) {
        step = 'DAY';
        durationParam.start = startTime.format(stepFormatMap.DAY);
        durationParam.end = endTime.format(stepFormatMap.DAY);
      } else {
        step = 'DAY';
        durationParam.start = startTime.format(stepFormatMap.DAY);
        durationParam.end = endTime.format(stepFormatMap.DAY);
      }
      durationParam.step = step;
      return durationParam;
    }

    onMounted(() => {});

    return {
      props,
      formRef,
      formState,
      disabledDate,
      onCalendarChange,
      onOpenChange,
      onTimeRangeChange,
      onTenantChange,
      onAppChange,
      maxTagCount,
      maxTagTextLength,
      services,
      serviceOptions,
      serviceDisabled,
      apps,
      appOptions,
      appDisabled,
      tenants,
      tenantOptions,
      tenantDisabled,
      timeRange,
      timeRangeOptions,
      showTime,
      formItemLayout,
      resetForm,
      onSubmit,
      format,
    };
  },
});
</script>
